package com.yang.Dp.bags;

/**
 * @Author: yang
 * @Description: 有一堆石头，用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。
 * 每一回合，从中选出任意两块石头，然后将它们一起粉碎。假设石头的重量分别为 x 和 y，且 x <= y。那么粉碎的可能结果如下：
 *     如果 x == y，那么两块石头都会被完全粉碎；
 *     如果 x != y，那么重量为 x 的石头将会完全粉碎，而重量为 y 的石头新重量为 y-x。
 * 最后，最多只会剩下一块 石头。返回此石头 最小的可能重量 。如果没有石头剩下，就返回 0。
 * @Date: Created in 17:24 2022/8/10
 * @Modified By:
 */
public class LeetCode1049 {
}
class LeetCode1049Solution {
    // 如果本质就是让一堆石头 变成两堆石头 然后求剩余最优的数字
    // 1.dp[i] 表示当前容量从石头堆中能够获得的最大重量
    // 2.递推公式 dp[i] = Math.max(dp[j], dp[j - stones[i] + stones[i]])
    // 3.如何初始化  全部初始化为0
    // 4.循环方式 外层循环物品 内层循环容量且容量倒序避免重复装入
    public int lastStoneWeightII(int[] stones) {
        int sum = 0;
        for(int stone : stones){
            sum += stone;
        }
        int target = sum >> 1;
        int[] dp = new int[target + 1];

        for(int i = 0; i < stones.length; i ++){
            for(int j = target; j >= stones[i]; j --){
                // 这里其实就是理解为要么放 要么不放
                dp[j] = Math.max(dp[j], dp[j - stones[i]] + stones[i]);
            }
        }
        return sum - dp[target]*2;
    }
}
